import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class GitUtil {
    //git工具类

    //存档特殊文件夹
    public static final String MY_GIT_UTIL_PATH = ".myGitUtil";


    //私有方法,执行cmd命令,返回值:结果字符串
    private static String execCmd(String cmd) {
        StringBuilder result = new StringBuilder();
        try {
            Process process = Runtime.getRuntime().exec(cmd);
            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            String line;
            while ((line = reader.readLine()) != null) {
                result.append(line).append("\n");
            }
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        return result.toString();
    }

    //开放方法:检查当前文件夹是否为git仓库
    public static boolean isGitRepository() {
        String result = execCmd("git rev-parse --is-inside-work-tree");
        return result.contains("true") ;
    }

    //开放方法:初始化当前文件夹为git仓库
    public static void initGitRepository() {
        execCmd("git init");
    }

    //开放方法:进行存档
    public static void commit(String message) {
        //先判断是不是git仓库
        if (!isGitRepository()) {
            //创建
            initGitRepository();
        }
        //切换到master
        execCmd("git checkout master");
        //同时在自己的文件夹里面写入
        try {
            FileUtil.appendToFile(MY_GIT_UTIL_PATH, message);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        execCmd("git add .");
        execCmd("git commit -m \"" + message + "\"");

    }

    //开放方法:获取存档记录
    public static List<Records> getCommitHistory() {
        String resStr = execCmd("git log --all");
        List<String> commitHistory = parseGitLog(resStr);

        //进一步操作

        //读取文件
        String readNodes;
        try {
            readNodes = FileUtil.readFile(GitUtil.MY_GIT_UTIL_PATH);
        } catch (IOException e) {
            //throw new RuntimeException(e);
            //返回无
            return new ArrayList<>();
        }
        //切割
        String[] split = readNodes.split("\n");
        System.out.println("sp->"+ Arrays.toString(split));
        //倒序存放到List中
        List<String> nodeList = new ArrayList<>();
        for (int i = split.length - 1; i >= 0; i--) {
            nodeList.add(split[i]);
        }


        List<Records> records = new ArrayList<>();
        for (int i = 0; i < commitHistory.size(); i++) {
            //获取哈希
            String hash = commitHistory.get(i).split("\n")[0].split(" ")[1];


            //获取时间
            String time = commitHistory.get(i).split("\n")[2].split("Date:")[1];

            System.out.println("i="+i+"---size="+nodeList.size());
            //读取信息
            String node = nodeList.get(i);

            System.out.println(234);
            //打印
            //System.out.println("序号:"+(commitHistory.size()-i));
            //System.out.println(hash);
            //System.out.println(time);
            //System.out.println(node);
            //System.out.println("--------");

            Records nowRecords = new Records(hash, time,commitHistory.size()-i, node);

            //System.out.println("即将添加"+nowRecords);
            records.add(nowRecords);
        }

        //获取头
        String headHash = execCmd("git rev-parse HEAD");
        //替换
        headHash = headHash.replace("\n", "");
        for (Records record : records) {
            if (record.getHash().equals(headHash)) {
                record.setHead(true);
                System.out.println("发现头");
                break;
            }
            System.out.println("headHash is "+headHash);
            System.out.println("record.getHash() is "+record.getHash());
        }


        return records;
    }

    //私有方法,解析git log
    private static List<String> parseGitLog(String gitLogOutput) {
        List<String> result = splitCommits(gitLogOutput);

        return result;
    }

    //进行切割
    public static List<String> splitCommits(String allCommits) {
        List<String> commits = new ArrayList<>();
        String commitPattern = "(commit\\s+\\w+\\s*.*?(?=\\n\\n|\\Z))";
        Pattern pattern = Pattern.compile(commitPattern, Pattern.DOTALL);
        Matcher matcher = pattern.matcher(allCommits);

        while (matcher.find()) {
            commits.add(matcher.group());
        }

        return commits;
    }

    //开放方法:回到存档
    public static void backToRecord(String hash) {

        execCmd("git reset --hard " + hash);
        execCmd("git checkout master");
        System.out.println("执行了测试");
        execCmd("git reset --hard " + hash);
    }
    /**
     * 删除当前工作目录下的.git文件夹和.myGitUtil文件
     */
    public static void deleteGit() {
        // 获取当前工作目录
        File currentDir = new File(System.getProperty("user.dir"));

        // 删除.git文件夹
        deleteFolder(new File(currentDir, ".git"));

        // 删除.myGitUtil文件
        deleteFile(new File(currentDir, ".myGitUtil"));
    }

    /**
     * 删除指定的文件夹及其内容（递归删除）
     *
     * @param folder 要删除的文件夹
     * @return 如果文件夹被成功删除（或不存在），则返回true；否则返回false
     */
    private static boolean deleteFolder(File folder) {
        File[] files = folder.listFiles();
        if (files != null) {
            for (File file : files) {
                if (file.isDirectory()) {
                    deleteFolder(file);
                } else {
                    file.delete();
                }
            }
        }
        return folder.delete();
    }

    /**
     * 删除指定的文件
     *
     * @param file 要删除的文件
     * @return 如果文件被成功删除（或不存在），则返回true；否则返回false
     */
    private static boolean deleteFile(File file) {
        return file.delete();
    }

    // 开放方法: 前往指定的提交
    public static void go(String hash) {
        //还要,保存文件
        String save="";
        try {
            save = FileUtil.readFile(MY_GIT_UTIL_PATH);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        // 构建Git命令
        String[] cmd = {"git", "checkout", "-f",hash};

        try {
            // 执行Git命令
            Process process = Runtime.getRuntime().exec(cmd);

            // 等待命令执行完成并获取退出值（可选）
            int exitCode = process.waitFor();
            if (exitCode == 0) {
                System.out.println("Successfully checked out to commit: " + hash);
            } else {
                System.err.println("Failed to check out to commit: " + hash);
            }
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }

        //搞完了写回去

        try {
            //判断save最后是否是换行
            if(!save.endsWith("\n")){
                save+="\n";
            }
            FileUtil.overwriteFile(MY_GIT_UTIL_PATH, save);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }



    }


}
